<?php

namespace App\Http\Controllers\Home\User\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Model\Home_users;
use App\Model\Home_login_info;
use App\Http\Requests\Home\UserRegister;
use App\Http\Requests\Home\UserLogin;
use App\Http\Requests\Home\UserPhoneResetPwd;
use App\Http\Requests\Home\UserEmailResetPwd;
use App\Http\Requests\Home\UserDoResetPwd;
use Gregwar\Captcha\CaptchaBuilder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Common\CommonCodeApi;
use App\Http\Controllers\Common\CommonphoneCodeApi;
use App\Http\Controllers\Common\CommonEmailApi;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Session;



class UserApi extends Controller
{
   
    /**
     * [json json的返回信息]
     * @param  [type] $code [返回状态码]
     * @param  [type] $msg  [返回的信息内容]
     * @param  array  $data [返回所需数据]
     * @return [type]       [description]
     */
    public function json($code, $msg, $data = [])
    {
        return response()->json([
        'status' => $code,
        'msg' => $msg,
        'data' => $data,
        ]);
    }

    public function handlerLogin(UserLogin $Request)
    {   

        $name = $Request->input('name');
        $pwd = $Request->input('pwd');
        $autologin = $Request->input('autologin');
        $sign_time = date('Y-m-d H:i:s', time());

        $user = Home_users::select('username', 'password', 'id', 'nickname', 'sex', 'phone', 'email', 'user_level_id', 'user_score')
            ->where('username', $name)
                ->first();

        if (!$user){
            return $this->json(1300, '用户不存在');
            exit;
        }

        //检查用户最近30分钟密码错误次数
        $res = $this->checkPassWrongTime($user->id);

        //错误次数超过限制次数
        if ($res === false) {
            return $this->json(1303, '输入密码错误次数过多，为保证账户安全，系统将您账号锁定30min');
        }

        if (password_verify($pwd, $user->password)) {
            //将用户数据放到session
            Home_users::where('id', $user->id)->update(['sign_time' => $sign_time]);
            unset($user->password);
            $Request->session()->put('home_user', $user);
            Home_login_info::where('uid', $user->id)->delete();

			//将session的购物车存入用户
            if ( Session::has('visitorCart') ) {
				$addRes = $this->addToRedisCart();
				if ( $addRes ) {
					//将session购物车删除
					Session::remove('visitorCart');
				}
            }



            return $this->json(1200, '登录成功');
            exit;

        } else {

            //记录密码错误次数
            $this->recordPassWrongTime($user->id);

            return $this->json(1302, '登录失败'.$res.'次');
            exit;
        }


    }

	/**
	 *  此方法将登录前的游客购物车添加到用户redis购物车中;
	 * @author 刘冠生
	 * @return mixed
	 */
	public function addToRedisCart()
	{
		$sessionCart = Session::get('visitorCart');
		$uid = Session::get('home_user')['id'];
		//判断---redis---中是否有该用户购物车信息,没有就执行真区间
		foreach ($sessionCart as $item) {
			$pid = $item[0];
			$itemNum = $item[2];
			$goodsid = DB::table('goods_price')->select('gid')->find($pid);
			$gid = $goodsid->gid;
//			dd($gid);
			if (!Redis::hkeys("userCart:{$uid}")) {
				// reddis没有购物车信息,查询商品数据库信息,并存入redis,$goodsInfo 是一个集合
				$goodsInfo = DB::table('goods_price as gp')
					->select(['g.gname', 'gp.id', 'gp.price', 'gp.storage', 'size', 'color', 'discount_price', 'gp.state', 'g.pic'])
					->leftJoin('goods as g', 'g.id', '=', 'gp.gid')
					->where('gp.id', '=', "{$pid}")
					->get()->toArray();

				foreach ($goodsInfo as $item) {
					//准备购物车数组,[pid=>商品详细信息]
					$cartArr = [
						$pid,
						['id' => $item->id,
							'gname' => $item->gname,
							'price' => $item->price,
							'storage' => $item->storage,
							'size' => $item->size,
							'color' => $item->color,
							'discount_price' => $item->discount_price,
							'state' => $item->state,
							'pic' => $item->pic,
						],
						$itemNum,
					];
				}
				//将数据json编码
				$cartToJson = json_encode($cartArr);
//					var_dump($cartArr);
				//创建一个新的用户购物车
				$res = Redis::hset("userCart:{$uid}", "userCart:{$gid}:{$pid}", $cartToJson);

				//设置键值有效时间30*24*60*60秒
				$validTime = 30 * 24 * 60 * 60;
				$return = Redis::expire("userCart:{$uid}", $validTime);

				//返回处理结果
				return $res;

				//---Redis---有的加就直接加入购物车
			} else {

				//判断该商品在不在---redis---购物车里面,不在就执行真区间
				if (!Redis::hexists("userCart:{$uid}", "userCart:{$gid}:{$pid}")) {
					//在数据库查找该商品信息,并存入redis
					$goodsInfo = DB::table('goods_price as gp')
						->select(['g.gname', 'gp.id', 'gp.price', 'gp.storage', 'size', 'color', 'discount_price', 'gp.state', 'g.pic'])
						->leftJoin('goods as g', 'g.id', '=', 'gp.gid')
						->where('gp.id', '=', "{$pid}")
						->get()->toArray();
					foreach ($goodsInfo as $item) {
						//准备购物车数组,[pid=>商品详细信息]
						$cartArr = [
							$pid,
							['id' => $item->id,
								'gname' => $item->gname,
								'price' => $item->price,
								'storage' => $item->storage,
								'size' => $item->size,
								'color' => $item->color,
								'discount_price' => $item->discount_price,
								'state' => $item->state,
								'pic' => $item->pic,
							],
							$itemNum,
						];
					}
//					var_dump($cartArr);
					//将数据json编码
					$cartToJson = json_encode($cartArr);
					//存入redis 购物车
					$res = Redis::hset("userCart:{$uid}", "userCart:{$gid}:{$pid}", $cartToJson);
					//返回处理结果
					return $res;

					//若有该商品,就将该商品从redis的"userCart:{$uid}" 键里面取出并加数量, 再重新压入redis
				} else {

					//查询商品信息,并解码
					$cartInRedis = json_decode(Redis::hget("userCart:{$uid}", "userCart:{$gid}:{$pid}"));
//					var_dump($cartInRedis);
					//将新增商品数量加入
					$cartInRedis[2] = $cartInRedis[2] ? $itemNum + $cartInRedis[2] : $itemNum;
					//再重新将商品放入购物车
					$cartToJson = json_encode($cartInRedis);

					$res = Redis::hdel("userCart:{$uid}", "userCart:{$gid}:{$pid}");

					$res = Redis::hset("userCart:{$uid}", "userCart:{$gid}:{$pid}", $cartToJson);
					var_dump($res);
					//返回处理结果
					return $res;
				}
			}
		}
    }
    
    //记录密码输出信息
    protected function recordPassWrongTime($uid)
    {

        //ip2long()函数可以将IP地址转换成数字
        $ip = ip2long($_SERVER['REMOTE_ADDR']);

        $time = date('Y-m-d H:i:s');

        Home_login_info::insert([

            'uid'               => $uid,
            'lastlogin_ip'      => $ip,
            'lastlogin_time'    => $time,
            'pass_wrong_status' => 2,
        ]);
    }

    /**
     * [checkPassWrongTime description]
     * @param   $uid   [用户的ID]
     * @param   $min   [锁定时间]
     * @param   $wTime [错误次数]
     * @return         [错误次数超过返回false,其他返回错误次数,提示用户]
     */
    protected function checkPassWrongTime($uid, $min=30, $wTime=3)
    {

        if (empty($uid)) {

            throw new \Exception('第一个参数不能为空');
            
        }

        $time = date('Y-m-d H:i:s', time());
        $overprevTime = date('Y-m-d H:i:s', time() - $min*60);


        //$prevTime = time() - $min*60;

        //用户所在登录ip
        $ip = ip2long($_SERVER['REMOTE_ADDR']);

        $data = Home_login_info::select(['id', 'uid', 'lastlogin_ip', 'lastlogin_time', 'pass_wrong_status'])
        ->where('uid', $uid)
            ->orwhere('pass_wrong_status', 2)
                ->orwhere('lastlogin_ip', $ip)
                    ->whereBetween('lastlogin_time', [$overprevTime, $time])
                        ->get();

        //统计错误次数
        $wrongTime = count($data);

        //判断错误次数是否超过限制次数
        if ($wrongTime >= $wTime) {
            return false;
        }

        return $wrongTime;
    }

    public function existsRegister(Request $Request)
    { 
        $name = $Request->input('name');
        $email = $Request->input('email');
        $phone = $Request->input('phone');
        
        //检查用户是否存在
        $Home_name = Home_users::select(['username'])->where('username', $name)->first();
        if ($Home_name) {
            return $this->json(1404, '用户已存在');
        }

        //检查邮箱是否存在
        $Home_email = Home_users::select(['email'])->where('email', $email)->first();
        if ($Home_email) {
            return $this->json(1403, '邮箱已存在');

        }   


        //检查手机是否存在
         $Home_phone = Home_users::select(['phone'])->where('phone', $phone)->first();
        if ($Home_phone) {
            return $this->json(1402, '手机号已存在');
        }

    }

    public function handlerRegister(UserRegister $Request)
    {   
        // $boolphone = true;
        $name = $Request->input('name');
        $email = $Request->input('email');
        $phone = $Request->input('phone');
        $phonecode = $Request->input('phonecode');
        $code = $Request->input('code');
        $pwd = $Request->input('pwd');
        $confirmPwd = $Request->input('confirmPwd');
        $agree = $Request->input('agree');


        if ($pwd !== $confirmPwd) {
            return $this->json(1407, '密码不一致');
            exit;
        }

        $boolcode = CommonCodeApi::CheckCode($Request, 'code');

        if (!$boolcode) {
            return $this->json(1405, '验证码错误');
        }

        $boolphone = CommonphoneCodeApi::CheckphoneCode($Request, 'phonecode');

        if (!$boolphone) {
            return $this->json(1406, '手机验证码错误');
        }


        $booluser = Home_users::select(['username', 'email', 'phone'])
        ->where('username', $name)
            ->orwhere('email', $email)
                ->orwhere('phone', $phone)->first();

        

        if(!$booluser && $boolcode && $boolphone) {

            Home_users::insert([

                'username' => $name,
                'email'    => $email,
                'phone'    => $phone,
                'password' => password_hash($pwd, PASSWORD_DEFAULT),
            ]);
            return $this->json(1200, '注册成功');
        }
        
            return $this->json(1400, '注册失败');
    }

    public function phoneRePwd(UserPhoneResetPwd $Request)
    {   
        //$boolphone = true;
        $phone = $Request->input('phone');
        $phonecode = $Request->input('phonecode');
        $code = $Request->input('code');

        $user = Home_users::select(['phone'])->where('phone', $phone)->first();

        if (!$user) {

            return $this->json(1400, '该手机号的用户不存在');          
        }

        $boolcode = CommonCodeApi::CheckCode($Request, 'code');

        if (!$boolcode) {

            return $this->json(1401, '验证码错误');
        }

        $boolphone = CommonphoneCodeApi::CheckphoneCode($Request, 'phonecode');

        if (!$boolphone) {

            return $this->json(1402, '手机验证码错误');
        }

        if($user && $boolcode && $boolphone) {

            return $this->json(1201, $user->phone);
        }
        
            return $this->json(1300, '数据传输失败,请重试');
    }

    public function emailRePwd(UserEmailResetPwd $Request)
    {   
        //$boolemail = true;
        $email = $Request->input('email');
        $emailcode = $Request->input('emailcode');
        $code = $Request->input('code');

        $user = Home_users::select(['email'])->where('email', $email)->first();

        if (!$user) {

            return $this->json(1400, '该邮箱的用户不存在');          
        }

        $boolcode = CommonCodeApi::CheckCode($Request, 'code');

        if (!$boolcode) {

            return $this->json(1401, '验证码错误');
        }

        $boolemail = CommonEmailApi::CheckEmailCode($Request, 'emailcode');

        if (!$boolemail) {

            return $this->json(1402, '邮箱验证码错误');
        }

        if($user && $boolcode && $boolemail) {

            return $this->json(1200, $user->email);
        }
        
            return $this->json(1300, '数据传输失败,请重试');
    }

    public function forResetPwd(UserDoResetPwd $Request)
    {
        $pwd = $Request->input('pwd');
        $confirmPwd = $Request->input('confirmPwd');
        $Modifycondition = $Request->Modifycondition;

        
        if ($pwd !== $confirmPwd) {
            return $this->json(1401, '密码不一致');
            exit;
        }


        $pwd = password_hash($pwd, PASSWORD_DEFAULT);


        $user = Home_users::where('phone', $Modifycondition)
            ->orwhere('email', $Modifycondition)
                ->update(['password' => $pwd]);

        if ($user) {

            return $this->json(1200, '重置成功');
        }

            return $this->json(1400, '重置失败,请重试');
    }

    public function removeUserInfo()
    {
        Session::forget('home_user');

        $url = route('index');
        return redirect()->route('index');
    }
}
